package com.lantosec.hmrp.core.shiro;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.lantosec.hmrp.modules.system.entity.SysUser;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;

public class TokenUtil {

    public static final long EXPIRE_TIME = 12 * 60 * 60;//token到期时间
    public static final long REFRESH_EXPIRE_TIME = 12 * 60 * 60 * 24;//RefreshToken到期时间
    private static final String TOKEN_SECRET = "ljdyaishijin**3nkjnj??";  //密钥盐

    public static String getToken(){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if(Objects.isNull(attributes)){
            return null;
        }
        HttpServletRequest request = attributes.getRequest();
        return request.getHeader("token");
    }


    public static String sign(SysUser user, Long currentTime) {
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.SECOND, (int)EXPIRE_TIME);
        Date expiresDate = nowTime.getTime();

        String token = null;
        try {
            //Date expireAt = new Date(currentTime + EXPIRE_TIME);
            token = JWT.create()
                    .withIssuer("auth0")//发行人
                    .withClaim("userName", user.getUsername())
                    .withClaim("passWord", user.getPassword())
                    .withClaim("name", user.getName())
                    .withClaim("userId", user.getUserId())
                    .withClaim("deptId", user.getDeptId())
                    .withClaim("permission",user.getPermission())
                    .withClaim("currentTime", currentTime)
                    .withIssuedAt(new Date())
                    .withExpiresAt(expiresDate)//过期时间
                    .sign(Algorithm.HMAC256(TOKEN_SECRET));
        } catch (IllegalArgumentException | JWTCreationException je) {

        }
        return token;
    }


    /**
     * @param : [token]
     * @return : java.lang.Boolean
     * @throws :
     * @Description ：token验证
     */
    public static Boolean verify(String token) throws Exception {

        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();//创建token验证器
        DecodedJWT decodedJWT = jwtVerifier.verify(token);
        System.out.println("认证通过：");
        System.out.println("account: " + decodedJWT.getClaim("account").asString());
        System.out.println("过期时间：      " + decodedJWT.getExpiresAt());
        return true;
    }

    private static String getClaimByKey(String key) {
        try {
            String token = getToken();
            if (StringUtils.isEmpty(token)) {
                return null;
            }
            DecodedJWT decodedJWT = JWT.decode(token);
            return decodedJWT.getClaim(key).asString();

        } catch (Exception e) {
            throw new AuthorizationException("获取登录信息失败");
        }
    }

    public static String getUserName() {
        return getClaimByKey("userName");
    }

    public static String getPassWord() {
        return getClaimByKey("passWord");
    }

    public static String getName() {
        return getClaimByKey("name");
    }

    public static String getUserId() {
        return getClaimByKey("userId");
    }

    public static String getDeptId() {
        return getClaimByKey("deptId");
    }

    public static String getPermission() {
        return getClaimByKey("permission");
    }

    public static Long getCurrentTime(String token) {
        try {
            DecodedJWT decodedJWT = JWT.decode(token);
            return decodedJWT.getClaim("currentTime").asLong();
        } catch (Exception e) {
            throw  new AuthorizationException("获取登录信息失败");
        }
    }

}
